﻿using Newtonsoft.Json;
using Request;
using Request.Handler;
using Response;
using System;
using System.IO;
using System.Linq;
using System.Web.Mvc;

namespace Web.Controllers
{
    public class HomeController : Controller
    {
        public const string dateFormat = "yyyy-MM-dd\\THH:mm:ss";

        /// <summary>
        /// Helper method to get POST request body.
        /// </summary>
        /// <returns>POST request body.</returns>
        private string getPostBody()
        {
            Stream req = Request.InputStream;
            req.Seek(0, System.IO.SeekOrigin.Begin);
            return new StreamReader(req).ReadToEnd();
        }

        /// <summary>
        /// Load request handler.
        /// </summary>
        /// <returns>JSON encoded response.</returns>
        [System.Web.Mvc.HttpGet]
        public ActionResult Load()
        {
            EF.GanttEntities db = new EF.GanttEntities();


            a所有5个Store的请求类 loadRequest = null;
            ulong? requestId = null;

            try
            {
                string json = Request.QueryString.Get("q");

                var gantt = new Core.Gantt();

                // decode request object
                try
                {
                    loadRequest = JsonConvert.DeserializeObject<a所有5个Store的请求类>(json);
                }
                catch (Exception)
                {
                    throw new Exception("Invalid load JSON");
                }

                // get request identifier
                requestId = loadRequest.requestId;

                // initialize response object
                var loadResponse = new _b整个Gantt的5个Store响应(requestId);

                // if a corresponding store is requested then add it to the response object

                if (loadRequest.calendars != null) loadResponse.setCalendars(gantt.getCalendars(), 1);
                if (loadRequest.assignments != null) loadResponse.setAssignments(gantt.getAssignments());
                if (loadRequest.tasks != null) loadResponse.setTasks(gantt.getTasks());
                if (loadRequest.resources != null) loadResponse.setResources(gantt.getResources());
                if (loadRequest.dependencies != null) loadResponse.setDependencies(gantt.getDependencies());

                // put current server revision to the response
                loadResponse.revision = gantt.getRevision();

                // just in case we make any changes during load request processing
                gantt.context.SaveChanges();

                return Content(JsonConvert.SerializeObject(loadResponse), "application/json");
            }
            catch (Exception e)
            {
                throw e;
                //return Content(JsonConvert.SerializeObject(new ErrorResponse(e, requestId)), "application/json");
            }
        }

        /// <summary>
        /// 合并变更。。。
        /// </summary>
        /// <param name="gantt"></param>
        /// <param name="table"></param>
        /// <param name="resp"></param>
        /// <returns></returns>
        protected _b各store变更完成后的响应 从PhantomMaps合并变更(Core.Gantt gantt, string table, _b各store变更完成后的响应 resp)
        {
            if (gantt.PhantomMaps.HasUpdatedRows(table))
            {
                if (resp == null) resp = new _b各store变更完成后的响应();
                var rows = gantt.PhantomMaps.GetUpdatedRows(table);
                resp.rows = resp.rows != null ? resp.rows.Concat(rows).ToList() : rows;
            }
            if (gantt.PhantomMaps.HasRemovedRows(table))
            {
                if (resp == null) resp = new _b各store变更完成后的响应();
                var removed = gantt.PhantomMaps.GetRemovedRows(table);
                resp.removed = resp.removed != null ? resp.removed.Concat(removed).ToList() : removed;
            }
            return resp;
        }

        /// <summary>
        /// Sync response handler.
        /// </summary>
        /// <returns>JSON encoded response.</returns>
        //[System.Web.Mvc.HttpPost]
        //public ActionResult Sync()
        //{
        //    ulong? requestId = null;
        //    _a整个Gantt的请求类 整个Gantt的请求 = null;

        //    try
        //    {
        //        string json = getPostBody();

        //        var gantt = new Core.Gantt();

        //        // decode request object
        //        try
        //        {
        //            整个Gantt的请求 = JsonConvert.DeserializeObject<_a整个Gantt的请求类>(json, 
        //                new Newtonsoft.Json.Converters.IsoDateTimeConverter { DateTimeFormat = dateFormat });
        //        }
        //        catch (Exception)
        //        {
        //            throw new Exception("Invalid sync JSON");
        //        }

        //        // initialize phantom to real Id maps
        //        gantt.PhantomMaps.InitRowsHolders();

        //        // get request identifier
        //        requestId = 整个Gantt的请求.requestId;

        //        // initialize response object
        //        var 变更完成后的响应体 = new _b变更完成后的响应(requestId);

        //        // Here we reject client's changes if we suspect that they are out-dated
        //        // considering difference between server and client revisions.
        //        // You can get rid of this call if you don't need such behavior.
        //        gantt.checkRevision(整个Gantt的请求.revision);

        //        // if a corresponding store modified data are provided then we handle them

        //        // first let's process added and updated records 

        //        日历数据库操作实现类 日历数据库操作实现 = null;
        //        if (整个Gantt的请求.日历部分的请求 != null)
        //        {
        //            日历数据库操作实现 = new 日历数据库操作实现类(gantt, dateFormat);
        //            变更完成后的响应体.calendars = 日历数据库操作实现.Handle(整个Gantt的请求.日历部分的请求, 日历数据库操作实现类.Rows.AddedAndUpdated);
        //        }
        //        资源数据库操作实现类 资源数据库操作实现 = null;
        //        if (整个Gantt的请求.resources != null)
        //        {
        //            资源数据库操作实现 = new 资源数据库操作实现类(gantt);
        //            变更完成后的响应体.resources = 资源数据库操作实现.Handle(整个Gantt的请求.resources, 资源数据库操作实现类.Rows.AddedAndUpdated);
        //        }
        //        任务数据库操作实现类 任务数据库操作实现 = null;
        //        if (整个Gantt的请求.tasks != null)
        //        {
        //            任务数据库操作实现 = new 任务数据库操作实现类(gantt, dateFormat);
        //            变更完成后的响应体.tasks = 任务数据库操作实现.Handle(整个Gantt的请求.tasks, 任务数据库操作实现类.Rows.AddedAndUpdated);
        //        }
        //        分配数据库操作实现类 分配数据库操作实现 = null;
        //        if (整个Gantt的请求.assignments != null)
        //        {
        //            分配数据库操作实现 = new 分配数据库操作实现类(gantt);
        //            变更完成后的响应体.assignments = 分配数据库操作实现.Handle(整个Gantt的请求.assignments, 分配数据库操作实现类.Rows.AddedAndUpdated);
        //        }
        //        关系依赖数据库操作实现类 关系依赖数据库操作实现 = null;
        //        if (整个Gantt的请求.dependencies != null)
        //        {
        //            关系依赖数据库操作实现 = new 关系依赖数据库操作实现类(gantt);
        //            变更完成后的响应体.dependencies = 关系依赖数据库操作实现.Handle(整个Gantt的请求.dependencies, 关系依赖数据库操作实现类.Rows.AddedAndUpdated);
        //        }


        //        // then let's process records removals
        //        //  先添加，再做删除，若一起操作，数据上面可能会有错？未验证

        //        if (整个Gantt的请求.dependencies != null)
        //            变更完成后的响应体.dependencies = 关系依赖数据库操作实现.HandleRemoved(整个Gantt的请求.dependencies, 变更完成后的响应体.dependencies);

        //        if (整个Gantt的请求.assignments != null)
        //            变更完成后的响应体.assignments = 分配数据库操作实现.HandleRemoved(整个Gantt的请求.assignments, 变更完成后的响应体.assignments);

        //        if (整个Gantt的请求.tasks != null)
        //            变更完成后的响应体.tasks = 任务数据库操作实现.HandleRemoved(整个Gantt的请求.tasks, 变更完成后的响应体.tasks);

        //        if (整个Gantt的请求.resources != null)
        //            变更完成后的响应体.resources = 资源数据库操作实现.HandleRemoved(整个Gantt的请求.resources, 变更完成后的响应体.resources);

        //        if (整个Gantt的请求.日历部分的请求 != null)
        //            变更完成后的响应体.calendars = 日历数据库操作实现.HandleRemoved(整个Gantt的请求.日历部分的请求, 变更完成后的响应体.calendars);

        //        // we also return implicit modifications made by server
        //        // (implicit records updates/removals caused by data references)
        //        // 部分数据库形成的隐式修改，也要增加到响应里面去。

        //        变更完成后的响应体.calendars = 从PhantomMaps合并变更(gantt, "calendars", 变更完成后的响应体.calendars);
        //        变更完成后的响应体.tasks = 从PhantomMaps合并变更(gantt, "tasks", 变更完成后的响应体.tasks);
        //        变更完成后的响应体.resources = 从PhantomMaps合并变更(gantt, "resources", 变更完成后的响应体.resources);
        //        变更完成后的响应体.assignments = 从PhantomMaps合并变更(gantt, "assignments", 变更完成后的响应体.assignments);
        //        变更完成后的响应体.dependencies = 从PhantomMaps合并变更(gantt, "dependencies", 变更完成后的响应体.dependencies);

        //        // put current server revision to the response
        //        变更完成后的响应体.revision = gantt.getRevision();

        //        gantt.context.SaveChanges();

        //        return Content(JsonConvert.SerializeObject(变更完成后的响应体), "application/json");
        //    }
        //    catch (Exception e)
        //    {
        //        return Content(JsonConvert.SerializeObject(new 异常响应(e, requestId)), "application/json");
        //    }
        //}

        /// <summary>
        /// Back-end test handler providing database cleanup.
        /// TODO: WARNING! This code clears the database. Please get rid of this code before running it on production.
        /// </summary>
        /// <returns>Empty string.</returns>
        public string Reset()
        {
            var gantt = new Core.Gantt();

            gantt.Reset();
            gantt.context.SaveChanges();

            return "";
        }
    }
}